package cn.iocoder.yudao.module.trade.aftersale.controller.admin;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.business.basic.pojo.vo.UserSimpleVO;
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.api.member.user.MemberUserApi;
import cn.iocoder.yudao.module.api.shop.admin.ShopUserApi;
import cn.iocoder.yudao.module.trade.aftersale.convert.AfterSaleConvert;
import cn.iocoder.yudao.module.trade.aftersale.dal.dataobject.AfterSaleDO;
import cn.iocoder.yudao.module.trade.aftersale.dal.dataobject.AfterSaleLogDO;
import cn.iocoder.yudao.module.trade.aftersale.service.AfterSaleLogService;
import cn.iocoder.yudao.module.trade.aftersale.service.AfterSaleService;
import cn.iocoder.yudao.module.trade.aftersale.service.ZXHXAfterSaleSyncService;
import cn.iocoder.yudao.module.trade.aftersale.vo.*;
import cn.iocoder.yudao.module.trade.order.dal.dataobject.TradeOrderDO;
import cn.iocoder.yudao.module.trade.order.dal.dataobject.TradeOrderItemDO;
import cn.iocoder.yudao.module.trade.order.service.TradeOrderQueryService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static cn.iocoder.yudao.module.api.trade.ErrorCodeConstants.AFTER_SALE_ADDRESS_MISSING;

@Tag(name = "管理后台 - 售后订单")
@RestController
@RequestMapping("/trade/after-sale")
@Validated
@Slf4j
public class AfterSaleController {

    @Resource
    private AfterSaleService afterSaleService;
    @Resource
    private AfterSaleLogService afterSaleLogService;
    @Resource
    private ZXHXAfterSaleSyncService zxhxAfterSaleSyncService;
    @Resource
    private TradeOrderQueryService tradeOrderQueryService;

    @Resource
    private ShopUserApi shopUserApi;
    @Resource
    private MemberUserApi memberUserApi;

    @GetMapping("/page")
    @Operation(summary = "获得售后订单分页")
    @PreAuthorize("@ss.hasPermission('trade:after-sale:query')")
    public CommonResult<PageResult<AfterSaleRespPageItemVO>> getAfterSalePage(@Valid AfterSalePageReqVO pageVO) {
        // 查询售后
        PageResult<AfterSaleDO> pageResult = afterSaleService.getAfterSalePage(pageVO);
        if (CollUtil.isEmpty(pageResult.getList())) {
            return success(PageResult.empty());
        }
        // 查询用户
        Map<Long, UserSimpleVO> memberUsers = memberUserApi.getUserSimpleMap(
                convertSet(pageResult.getList(), AfterSaleDO::getUserId));
        return success(AfterSaleConvert.INSTANCE.convertPage(pageResult, memberUsers));
    }

    @GetMapping("/get-detail")
    @Operation(summary = "获得售后订单详情")
    @Parameter(name = "id", description = "售后编号", required = true, example = "1")
    @PreAuthorize("@ss.hasPermission('trade:after-sale:query')")
    public CommonResult<AfterSaleDetailRespVO> getOrderDetail(@RequestParam("id") Long id) {
        // 查询订单
        AfterSaleDO afterSale = afterSaleService.getAfterSale(id);
        if (afterSale == null) {
            return success(null);
        }
        if (StrUtil.isNotBlank(afterSale.getSupplyRelatedNo())) {
            zxhxAfterSaleSyncService.syncAfterSaleInfoAsync(afterSale.getSupplyRelatedNo(), afterSale);
        }
        // 查询订单
        TradeOrderDO order = tradeOrderQueryService.getOrder(afterSale.getOrderId());
        // 查询订单项
        TradeOrderItemDO orderItem = tradeOrderQueryService.getOrderItem(afterSale.getOrderItemId());
        // 拼接数据
        UserSimpleVO user = memberUserApi.getUser(afterSale.getUserId());
        List<AfterSaleLogDO> logs = afterSaleLogService.getAfterSaleLogList(afterSale.getId());
        return success(AfterSaleConvert.INSTANCE.convert(afterSale, order, orderItem, user, logs));
    }

    @PostMapping("/agree")
    @Operation(summary = "同意售后（无寄送地址，卖家，单个产品）")
    @Parameter(name = "id", description = "售后编号", required = true, example = "1")
    @PreAuthorize("@ss.hasRole('shop_admin')")
    public CommonResult<Boolean> agreeAfterSale(@RequestParam("id") Long id) {
        AfterSaleAgreeReqVO reqVO = new AfterSaleAgreeReqVO();
        reqVO.setId(id);
        afterSaleService.agreeAfterSale(getShopId(), reqVO);
        return success(true);
    }

    @PostMapping(value = "/agree-by-order")
    @Operation(summary = "同意售后（仅退款，无寄送地址，卖家，整单）")
    @Parameter(name = "orderId", description = "订单编号", required = true, example = "1")
    @PreAuthorize("@ss.hasRole('shop_admin')")
    public CommonResult<Boolean> agreeAfterSaleByOrder(@RequestParam("orderId") Long orderId) {
        AfterSaleAgreeReqVO reqVO = new AfterSaleAgreeReqVO();
        reqVO.setOrderId(orderId);
        afterSaleService.agreeAfterSale(getShopId(), reqVO);
        return success(true);
    }

    @PostMapping("/agree-address")
    @Operation(summary = "同意售后（退货退款，有寄送地址，卖家）")
    @PreAuthorize("@ss.hasRole('shop_admin')")
    public CommonResult<Boolean> agreeAfterSaleAddress(@Valid @RequestBody AfterSaleAgreeReqVO reqVO) {
        if (reqVO.getDeliveryAreaId() == null || reqVO.getDeliveryAreaId() == 0
            || StrUtil.isBlank(reqVO.getDeliveryDetailAddress())) {
            return error(AFTER_SALE_ADDRESS_MISSING);
        }
        afterSaleService.agreeAfterSale(getShopId(), reqVO);
        return success(true);
    }

    @PostMapping("/refuse")
    @Operation(summary = "拒绝收货（卖家）")
    @Parameter(name = "id", description = "售后编号", required = true, example = "1")
    @PreAuthorize("@ss.hasRole('shop_admin')")
    public CommonResult<Boolean> refuseAfterSale(AfterSaleRefuseReqVO reqVO) {
        afterSaleService.refuseAfterSale(getShopId(), reqVO);
        return success(true);
    }

    @PostMapping("/disagree")
    @Operation(summary = "拒绝售后（卖家）")
    @PreAuthorize("@ss.hasRole('shop_admin')")
    public CommonResult<Boolean> disagreeAfterSale(@RequestBody AfterSaleDisagreeReqVO reqVO) {
        afterSaleService.disagreeAfterSale(getShopId(), reqVO);
        return success(true);
    }

    @PostMapping("/receive")
    @Operation(summary = "确认收货（卖家，单个产品）")
    @Parameter(name = "id", description = "售后编号", required = true, example = "1")
    @PreAuthorize("@ss.hasRole('shop_admin')")
    public CommonResult<Boolean> receiveAfterSale(@RequestParam("id") Long id) {
        afterSaleService.receiveAfterSale(getShopId(), id);
        return success(true);
    }

    @PostMapping(value = "/receive-by-order")
    @Operation(summary = "确认收货（卖家，整单）")
    @Parameter(name = "orderId", description = "订单编号", required = true, example = "1")
    @PreAuthorize("@ss.hasRole('shop_admin')")
    public CommonResult<Boolean> receiveAfterSaleByOrder(@RequestParam("orderId") Long orderId) {
        afterSaleService.receiveAfterSaleByOrder(getShopId(), orderId);
        return success(true);
    }

    @PostMapping(value = "/refund")
    @Operation(summary = "确认退款（平台，单个产品）", description = "线上原路退款可能会失败，这时需要线下打款给用户然后执行此接口确认已退款")
    @Parameter(name = "id", description = "售后编号", required = true, example = "1")
    @PreAuthorize("@ss.hasAnyRoles('super_admin','tenant_admin','platform_admin','finance')")
    public CommonResult<Boolean> refundAfterSale(@RequestParam("id") Long id) {
        afterSaleService.refundAfterSale(id);
        return success(true);
    }

    @PostMapping(value = "/refund-by-order")
    @Operation(summary = "确认退款（平台，整单）", description = "线上原路退款可能会失败，这时需要线下打款给用户然后执行此接口确认已退款")
    @Parameter(name = "orderId", description = "订单编号", required = true, example = "1")
    @PreAuthorize("@ss.hasAnyRoles('super_admin','tenant_admin','platform_admin','finance')")
    public CommonResult<Boolean> refundAfterSaleByOrder(@RequestParam("orderId") Long orderId) {
        afterSaleService.refundAfterSaleByOrder(orderId);
        return success(true);
    }

    private Long getShopId() {
        return shopUserApi.getShopIdByUserId(getLoginUserId(), UserTypeEnum.ADMIN.getValue());
    }

}
